'''
Created on 09/04/2009

@author: eh01
'''
from yarra import xmlconstants
from yarra.datastore import dsconstants, dsofactory
from yarra.datastore.dso import DSO
from yarra.datastore.dsstub import DSStub
from yarra.datastore.dst import DST
from yarra.event import eventconstants
from yarra.event.event import Event
from yarra.event.eventhandler import BaseEventHandler
from yarra.event.eventmanager import EventManager
from yarra.logindecorator import loginRequired
import datetime
import httplib
import re


class HTTPRequestPUTNodeMessageHandler(BaseEventHandler):

    @loginRequired
    def do(self, data):
        dso = data
        http_request = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST).get_literal()
        lock = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_LOCK).get_literal()
        http_request_header_content_type = dso.get_dst(subject=dsconstants.SUBJECT_HTTP_REQUEST_HEADER,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST_HEADER_CONTENT_TYPE).get_literal()
        body = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST_BODY).get_literal()                    
        
        dst1 = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_CONTENT_TYPE,
            literal=http_request_header_content_type)

        dst2 = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_TIMESTAMP,
            literal=datetime.datetime.now())

        dst3 = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_BODY,
            literal=body)
                        
        message_dso = DSO([dst1, dst2, dst3])
        
        ds_stub = DSStub()
        message_id = None
        
        # see if the message is a new message, or replacing a exisiting one
        matches_new_message = re.match('/node/(\d+)$', http_request.path)
        matches_replace_message = re.match('/node/(\d+)/(\d+)$', http_request.path)
        
        if matches_new_message:
            node_id = int(matches_new_message.group(1))
        else:
            node_id = int(matches_replace_message.group(1))
            message_id = int(matches_replace_message.group(2))

        # if the destination node is not currently connected then
        # don't add the message
        if ds_stub.is_node_currently_connected(node_id):
            message_id = ds_stub.add_message(node_id=node_id, 
                             message_id=message_id, 
                             message=message_dso)  
            response_body = xmlconstants.XML_VERSION_TAG + \
                            xmlconstants.MESSAGE_TAG_OPENING + \
                            xmlconstants.ID_TAG_OPENING + \
                            str(message_id) + \
                            xmlconstants.ID_TAG_CLOSING + \
                            xmlconstants.MESSAGE_TAG_CLOSING
            # create new dso        
            new_dso = dsofactory.create_dso_for_im_http_response_handler(httplib.FOUND, 
                                                                   xmlconstants.XML_CONTENT_TYPE, 
                                                                   response_body, 
                                                                   http_request, 
                                                                   lock)
            event_type = eventconstants.HTTP_RESPONSE_EVENT_TYPE
        else:
            # if the node is not currently connected, then send a error back
            new_dso = dsofactory.create_dso_for_http_error_handler(httplib.NOT_FOUND, 
                                             '', 
                                             http_request, 
                                             lock)
            event_type = eventconstants.HTTP_ERROR_EVENT_TYPE
            
        event = Event(event_type, new_dso)
        EventManager().add_event(event)